package com.dayu.finecomm.protocol.hd72;

import java.util.Calendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayu.finecomm.protocol.codec.Protocol;
import com.dayu.finecomm.protocol.codec.ProtocolDecoder;
import com.dayu.finecomm.protocol.pojo.TPacket;
import com.dayu.finecomm.protocol.pojo.TPacket.VType;
import com.dayu.finecomm.protocol.pojo.TSensor;
import com.dayu.finecomm.utils.Helpers;

import io.netty.buffer.ByteBuf;

/**
 * FDFD协议解析，详见父类
 * 
 * @author Chenjiawei
 *
 *         2017年5月11日
 */
@Protocol(XFDFDDecoder.PROTO)
public class XFDFDDecoder extends ProtocolDecoder<TPacket> {

	static final String PROTO = "RMTV2";

	private static final int MAGIC = 0xFDFD;
	static Logger LOGGER = LoggerFactory.getLogger(XFDFDDecoder.class);

	@Override
	public int checkStart(ByteBuf in) {
		return 0;
	}

	@Override
	public int check(ByteBuf in) {

		int c = in.readUnsignedShort();
		if (c != MAGIC) // 协议头检验
			return -1;

		in.skipBytes(52);

		int l = in.readUnsignedShort();

		in.skipBytes(l);

		int crcVal = in.readUnsignedShort();

		if (in.readUnsignedShort() != 0x0d0a)
			return -1;

		System.out.println(l + 8 + 52);

		ByteBuf b = in.slice(3, l + 52 + 1);
		if (crcVal != Helpers.crc16(b)) { // 校验
			return -1;
		}

		return (l + 52 + 8);
	}

	@Override
	public TPacket unpack(ByteBuf in) {

		in.skipBytes(4);

		String sn = in.readUnsignedInt() + "";

		in.skipBytes(46);

		int length = in.readUnsignedShort() + 60;
		System.out.println(length);

		in.skipBytes(9);

		int types = in.readUnsignedShort();
		in.readUnsignedByte();
		int interval = in.readUnsignedByte();
		Long nInterval = 0l;

		if (types == 0x0000) {
			return null;
		}

		if (interval == 0x30) {
			nInterval = 40l;
		} else if (interval == 0x31) {
			nInterval = 100l;
		} else if (interval == 0x32) {
			nInterval = 500l;
		} else if (interval == 0x33) {
			nInterval = 1 * 1000l;
		} else if (interval == 0x34) {
			nInterval = 5 * 1000l;
		} else if (interval == 0x35) {
			nInterval = 15 * 1000l;
		} else if (interval == 0x36) {
			nInterval = 30 * 1000l;
		} else if (interval == 0x37) {
			nInterval = 60 * 1000l;
		} else if (interval == 0x38) {
			nInterval = 5 * 60 * 1000l;
		} else if (interval == 0x39) {
			nInterval = 10 * 60 * 1000l;
		} else if (interval == 0x40) {
			nInterval = 15 * 60 * 1000l;
		} else if (interval == 0x41) {
			nInterval = 30 * 60 * 1000l;
		} else if (interval == 0x42) {
			nInterval = 60 * 60 * 1000l;
		} else if (interval == 0x43) {
			nInterval = 2 * 60 * 60 * 1000l;
		} else if (interval == 0x44) {
			nInterval = 4 * 60 * 60 * 1000l;
		} else if (interval == 0x45) {
			nInterval = 6 * 60 * 60 * 1000l;
		} else if (interval == 0x46) {
			nInterval = 12 * 60 * 60 * 1000l;
		} else if (interval == 0x47) {
			nInterval = 24 * 60 * 60 * 1000l;
		}

		in.skipBytes(1);

		int nYear = 2000 + in.readUnsignedByte();
		int nMonth = in.readUnsignedByte() - 1;
		int nDay = in.readUnsignedByte();
		int nHour = in.readUnsignedByte();
		int nMinute = in.readUnsignedByte();
		int nSecond = in.readUnsignedByte();

		Calendar c = Calendar.getInstance();
		c.set(nYear, nMonth, nDay, nHour, nMinute, nSecond);
		c.set(Calendar.MILLISECOND, 0);

		System.out.println(c.getTime());
		long sTime = c.getTime().getTime() + in.readUnsignedShort();

		TPacket s = new TPacket(VType.PPP, PROTO, sn, sTime);

		int i = 0;
		for (; in.readerIndex() < (length - 4);) {

			int type = in.readUnsignedByte();

			String channel;
			int no = in.readUnsignedByte();

			switch (type) {
			case 0x10: {// IEEE_754 反
				channel = "P" + no;
				byte[] bb = new byte[4];
				in.readBytes(bb);
				Float val = Float.intBitsToFloat(
						Integer.valueOf(Helpers.bytesToHexString(new byte[] { bb[3], bb[2], bb[1], bb[0] }), 16));
				s.sensors.add(new TSensor(channel, val, sTime + nInterval * i));
			}
				break;
			case 0x20: {
				channel = "K" + no;
				int val = in.readUnsignedByte();
				s.sensors.add(new TSensor(channel, val, sTime + nInterval * i));
			}
				break;
			case 0x21: {
				channel = "K" + no;
				int val = in.readUnsignedByte();
				s.sensors.add(new TSensor(channel, val, sTime + nInterval * i));
			}
				break;
			case 0x30: { // IEEE_754 反
				channel = "A" + no;
				byte[] bb = new byte[4];
				in.readBytes(bb);
				Float val = Float.intBitsToFloat(
						Integer.valueOf(Helpers.bytesToHexString(new byte[] { bb[3], bb[2], bb[1], bb[0] }), 16));
				s.sensors.add(new TSensor(channel, val, sTime + nInterval * i));
			}
				break;
			case 0x40: {
				channel = "M" + no;
				int val = in.readUnsignedShort();
				s.sensors.add(new TSensor(channel, val, sTime + nInterval * i));
			}
			case 0x50: {
				channel = "Q" + no;
				byte[] qq = new byte[4];
				in.readBytes(qq);
				String val = Helpers.bytesToHexString(qq);
				s.sensors.add(new TSensor(channel, Integer.parseInt(val), sTime + nInterval * i));
			}
			default:
				break;
			}

			i++;
		}

		return s;
	}

	@Override
	public Object timing() {
		return HD72Convention.timing();
	}

	@Override
	public byte[] echo() {
		return "@222".getBytes();
	}
}
